#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QFile>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QGraphicsView>
#include "vlc.h"

//#define VLC_API LIBVLC_API
#include "vlc_common.h"
#include "vlc_fourcc.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_fileDialog = new QFileDialog(this);
    m_fileDialog->setWindowTitle(tr("Open Video"));
    m_fileDialog->setDirectory(".");
    m_fileDialog->setNameFilter(tr("Video Files(*.mp4 *.mp3 *flv *3gp *rmvb *ivf)"));
    m_fileDialog->hide();
}

MainWindow::~MainWindow()
{
    delete ui;
}

//加载
bool MainWindow::load(const QString &filepath)
{
    if(filepath.isEmpty()){
        qDebug() << "filepath isEmpty";
        return false;
    }
    if(!QFile::exists(filepath)){
        qDebug() << "QFile no exists";
        return false;
    }
    bool bload = loadVlc(QDir::toNativeSeparators(filepath).toUtf8().constData());
    if(!bload){
        qDebug() << "bload no isEmpty";
        return false;
    }
    return true;
}

//播放
void MainWindow::play()
{
    if(libvlc_Ended == libvlc_media_get_state(m_media)){
        stop();
    }
    libvlc_media_player_play(m_mediaPlayer);
}

//暂停
void MainWindow::pause()
{
    if((bool)libvlc_media_player_is_playing(m_mediaPlayer)){
        m_bPlaying = false;
        libvlc_media_player_set_pause(m_mediaPlayer, 1);//暂停
    }
}

//停止
void MainWindow::stop()
{
    m_bPlaying = false;
    libvlc_media_player_stop(m_mediaPlayer);
}

//加载
#if 0
bool MainWindow::loadVlc(const QString &filepath)
{
    //设置沐曦硬件解码
    const char *vlc_args[] = {
        "--avcodec-codec=h264_mxvid"
    };

    //m_vlcInstance = libvlc_new(0, NULL);
    m_vlcInstance = libvlc_new(1, vlc_args);

    m_media = libvlc_media_new_path(m_vlcInstance, filepath.toUtf8().data());
    if(!m_media){
        freeVlc();
        return m_media;
    }
    qDebug() << "loadVlc" << qPrintable(filepath);
    m_mediaPlayer = libvlc_media_player_new_from_media(m_media);
    if(!m_mediaPlayer){
        freeVlc();
        return false;
    }
    libvlc_media_parse(m_media);
    libvlc_event_manager_t *em = libvlc_media_player_event_manager(m_mediaPlayer);
    libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerEndReached, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerStopped, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPlaying, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPaused, vlcEvents, this);

#ifdef Q_OS_WIN
    libvlc_media_player_set_hwnd(m_mediaPlayer, (void *)ui->label->winId());
#elif defined(Q_OS_LINUX)
    libvlc_media_player_set_xwindow(m_mediaPlayer, ui->label->winId());
#elif defined(Q_OS_MAC)
    libvlc_media_player_set_nsobject(m_mediaPlayer, (void *)ui->label->winId());
#endif

    return true;
}
#else
bool MainWindow::loadVlc(const QString &filepath)
{
    // 创建 VLC 实例
    const char *vlc_args[] = {
        "--avcodec-codec=auto"  // 默认使用自动选择解码器
    };

    m_vlcInstance = libvlc_new(1, vlc_args);
    if (!m_vlcInstance) {
        qDebug() << "Failed to create VLC instance";
        return false;
    }

    // 创建媒体对象
    m_media = libvlc_media_new_path(m_vlcInstance, filepath.toUtf8().data());
    if (!m_media) {
        freeVlc();
        return false;
    }

    qDebug() << "loadVlc" << qPrintable(filepath);

    // 解析媒体
    libvlc_media_parse(m_media);

    // 获取媒体信息
    libvlc_media_track_t **tracks;
    unsigned int track_count = libvlc_media_tracks_get(m_media, &tracks);

    for (unsigned int i = 0; i < track_count; ++i) {
        if (tracks[i]->i_type == libvlc_track_video) {
            // 获取视频编码类型
            uint32_t codec = tracks[i]->i_codec;
            switch (codec) {
                case VLC_CODEC_H264:
                    vlc_args[0] = "--avcodec-codec=h264_mxvid";
                    break;
                case VLC_CODEC_HEVC:
                    vlc_args[0] = "--avcodec-codec=hevc_mxvid";
                    break;
                case VLC_CODEC_AV1:
                    vlc_args[0] = "--avcodec-codec=av1_mxvid";
                    break;
                default:
                    break;
            }
            break;
        }
    }

    qDebug()<<"got codec options: "<<vlc_args[0];

    // 释放媒体信息
    libvlc_media_tracks_release(tracks, track_count);

    // 重新创建 VLC 实例并传递参数
    libvlc_release(m_vlcInstance);

    m_vlcInstance = libvlc_new(1, vlc_args);
    if (!m_vlcInstance) {
        qDebug() << "Failed to create VLC instance with codec parameters";
        return false;
    }

    // 重新创建媒体对象
    libvlc_media_release(m_media);
    m_media = libvlc_media_new_path(m_vlcInstance, filepath.toUtf8().data());
    if (!m_media) {
        freeVlc();
        return false;
    }

    // 创建媒体播放器
    m_mediaPlayer = libvlc_media_player_new_from_media(m_media);
    if (!m_mediaPlayer) {
        freeVlc();
        return false;
    }

    // 绑定事件
    libvlc_event_manager_t *em = libvlc_media_player_event_manager(m_mediaPlayer);
    libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerEndReached, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerStopped, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPlaying, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPaused, vlcEvents, this);

    // 根据平台选择合适的函数来设置窗口句柄
#ifdef Q_OS_WIN
    libvlc_media_player_set_hwnd(m_mediaPlayer, (void *)ui->label->winId());
#elif defined(Q_OS_LINUX)
    libvlc_media_player_set_xwindow(m_mediaPlayer, ui->label->winId());
#elif defined(Q_OS_MAC)
    libvlc_media_player_set_nsobject(m_mediaPlayer, (void *)ui->label->winId());
#endif

    return true;
}
#endif

//VLC事件
void MainWindow::vlcEvents(const libvlc_event_t *ev, void *param)
{
    Q_UNUSED(param);
    switch (ev->type) {
    case libvlc_MediaPlayerTimeChanged:
        break;
    case libvlc_MediaPlayerEndReached://不能在回调里调用stop();否则会卡死
        break;
    case libvlc_MediaPlayerStopped:
        qDebug() << "libvlc_MediaPlayerStopped";
        break;
    case libvlc_MediaPlayerPlaying:
        qDebug() << "libvlc_MediaPlayerPlay";
        break;
    case libvlc_MediaPlayerPaused:
        qDebug() << "libvlc_MediaPlayerPaused";
        break;
    }
}

//释放
void MainWindow::freeVlc()
{
    if(m_media){
        libvlc_media_release(m_media);
        m_media = Q_NULLPTR;
    }
    if(m_mediaPlayer){
        libvlc_media_player_stop(m_mediaPlayer);
        libvlc_media_player_release(m_mediaPlayer);
        m_mediaPlayer = Q_NULLPTR;
    }
    if(m_vlcInstance){
        libvlc_release(m_vlcInstance);
        m_vlcInstance = Q_NULLPTR;
    }
}

void MainWindow::on_pushButton_clicked()
{
    if(ui->pushButton->text() == "play") {
        play();
        ui->pushButton->setText("pause");
    } else if(ui->pushButton->text() == "pause") {
        pause();
        ui->pushButton->setText("play");
    }
}

void MainWindow::on_pB_Stop_clicked()
{
    stop();
    ui->pushButton->setText("play");
}

void MainWindow::on_pB_Open_clicked()
{
    if(m_vlcInstance) {
        freeVlc();
    }
    m_fileDialog->show();
    if(m_fileDialog->exec() == QDialog::Accepted) {
        QString path = m_fileDialog->selectedFiles()[0];
        ui->lB_Path->setText(path);
        load(path);
    }
}
